use base64::Engine;
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
use rand::distr::Alphanumeric;
use rand::Rng;
use sha2::{Digest, Sha256};

/// <br/>params: length(usize) 随机字符串长度
/// <br/>returns: String 生成的随机字符串
/// <br/>notes: 生成输入长度的随机的字符串
pub fn generate_random_str(length: usize) ->String{
    rand::rng()
        .sample_iter(&Alphanumeric)
        .take(length)
        .map(char::from)
        .collect()
}
/// <br/>returns: String 生成的64个长度高熵随机字符串
/// <br/>notes: Proof Key for Code Exchange
pub fn generate_pkce_verifier()->String{
    generate_random_str(64)
}

/// <br/>params:  verifier(&str) 输入64个长度高熵随机字符串
/// <br/>returns: String pkce-challenge
/// <br/>notes: 先对随机字符串sha256求hash再base64编码
pub fn calculate_pkce_challenge(verifier: &str)->String{
    let mut sha256_hasher = Sha256::new();
    Digest::update(&mut sha256_hasher, verifier.as_bytes());
    let hashed_result = sha256_hasher.finalize();
    URL_SAFE_NO_PAD.encode(hashed_result)
}

#[cfg(test)]
mod test{
    use super::*;
    #[test]
    pub fn test_generate_random_str(){
        let str = generate_random_str(32);
        println!("random str: {str}");
        assert_eq!(str.len(), 32);
    }
    #[test]
    pub fn test_calculate_pkce_challenge(){
        let verifier = generate_pkce_verifier();
        let challenge = calculate_pkce_challenge(&verifier);
        println!("pkce challenge: {}", challenge);
        assert_eq!(challenge.len(), 44);
    }
}
